<?php


namespace app\api\controller\v21;


use app\aliyun\controller\AliyunFilterWord;
use app\api\controller\v2\Auth;
use app\common\cachemodel\ZlcrAstr;
use app\common\cachemodel\ZlcrAstrAccount;
use app\common\cachemodel\ZlcrAstrAccountRecord;
use app\common\cachemodel\ZlcrAstrMessage;
use app\common\cachemodel\ZlcrContentCheck;
use app\common\cachemodel\ZlcrCustomReportGoods;
use app\common\cachemodel\ZlcrCustomReportQuestion;
use app\common\cachemodel\ZlcrCustomReportQuestionComment;
use app\common\cachemodel\ZlcrCustomReportQuestionInfo;
use app\common\cachemodel\ZlcrTag;
use app\common\lib\exception\ApiException;
use app\common\lib\SensorsData;
use app\common\lib\Util;
use Exception;
use think\Cache;
use think\Db;
use think\Env;
use think\response\Json;

class UserCustomReport extends Auth
{

    protected $completeAnswerTime;//接单后回答完成时长
    protected $refundTime;//退款接单时长

    protected function _initialize()
    {
        parent::_initialize();
        $this->completeAnswerTime = Env::get('queue.custom_report_answer6_delay');
        $this->refundTime = 60 * 15;
    }

    /**
     * 我的定制报告列表
     * @return Json
     * @throws Exception
     */
    public function myCustomReportList(): Json
    {
        $page = input('page/d', 1);
        $questionModel = new ZlcrCustomReportQuestion();
        //获取当前用户已支付报告进行的状态
        $questionReportInfo = $questionModel->getUserQuestionReportFromCache($this->user['id'], 2, [1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16], [], $page);
        if ($questionReportInfo['data']['data'])
        {
            $questionReportInfo['data']['data'] = $this->resetReport($questionReportInfo, $questionModel);
        }
        unset($questionReportInfo['ids']);
        return show(200, '请求成功', $questionReportInfo['data']);
    }

    /**
     * 重置报告数据格式
     * @param $questionReportInfo
     * @param $questionModel
     * @return array
     */
    private function resetReport($questionReportInfo, $questionModel)
    {
        $data = [];
        foreach ($questionReportInfo['ids'] as $datum)
        {
            $refundPercent = 1;//退款比例
            $is_cancel = false;//不可取消
            $pop = [
                'tips' => '当前订单不可取消',
                'type' => 1,
                'title' => '订单无法取消'
            ];
            switch ($questionReportInfo['data']['data'][$datum]['status'])
            {
                case 1://问题待审核
                    $status = 0;
                    $tips = '待审核';
                    $pop = [
                        'tips' => "订单正在审核中是否取消订单？",
                        'type' => 2,
                        'title' => '取消订单'
                    ];
                    $is_cancel = true;
                    break;//等待接单
                case 2://等待接单
                    //获取当前报告的队列排名
                    $num = $questionModel->getCustomReportQueueRank($questionReportInfo['data']['data'][$datum]['id']);
                    $status = 1;//等待接单
                    if ($num)
                    {
                        $tips = '当前队列等待 ' . $num;
                    } else
                    {
                        $tips = '即将接单，请稍等';
                    }
                    $pop = [
                        'tips' => "订单正在派发队列等待中\n是否取消订单？",
                        'type' => 2,
                        'title' => '取消订单'
                    ];
                    $is_cancel = true;
                    break;
                case 3://问题待解答
                case 4://解答待审核
                case 13://问题待解答（答案审核未通过)
                    $status = 2;//进行中

                    $payHour = date('G', $questionReportInfo['data']['data'][$datum]['pay_time']);//获取当前支付的小时
                    if ($payHour < 8 || $payHour >= 18)
                    {
                        $toTime = strtotime(date('Y-m-d 08:00:00', strtotime('+1day', $questionReportInfo['data']['data'][$datum]['pay_time'])));//获取第二天八点的时间戳
                        $tips = '预计时间：' . date('m.d H:i', ($toTime + $this->completeAnswerTime)) . '前';
                    } else
                    {
                        $tips = '预计时间：' . date('m.d H:i', $questionReportInfo['data']['data'][$datum]['astr_receiving_time'] + $this->completeAnswerTime) . '前';
                    }

                    // 判断接单时长
                    if (time() < $questionReportInfo['data']['data'][$datum]['astr_receiving_time'] + $this->refundTime)
                    {
                        $pop = [
                            'tips' => '该订单已被占星师接单，现在取消只返还订单金额的90%，是否取消订单？',
                            'type' => 2,
                            'title' => '取消订单'
                        ];
                        $is_cancel = true;
                        $refundPercent = 0.9;
                    } else
                    {
                        $pop = [
                            'tips' => '因该订单已被占星师接单超过15分钟，正在编辑中无法取消',
                            'type' => 1,
                            'title' => '订单无法取消'
                        ];
                    }
                    break;
                case 5://已完成待评价
                case 6://已评价待审核
                case 7://评价已审核完成
                    $status = 3;//已完成
                    $tips = '当前报告已完成';
                    break;
                case 10://问题审核未通过失效
                case 11://订单派发超时失效
                case 12://占星师超时未完成失效
                case 14://占星师拒答两次失效
                case 15://取消订单，金额退回90%
                case 16://取消订单，金额全部退回
                    $status = 4;//已失效
                    $tips = '7个工作日内退款至原支付账户';
                    break;
                default:
                    $status = 0;
                    $tips = '未支付';
                    break;
            }
            $data[] = [
                'id' => (string)$questionReportInfo['data']['data'][$datum]['id'],
                'question_name' => $questionReportInfo['data']['data'][$datum]['question_name'],
                'is_merge' => $questionReportInfo['data']['data'][$datum]['is_merge'],
                'order_id' => $questionReportInfo['data']['data'][$datum]['order_num'],
                'create_time' => date('Y.m.d H:i', $questionReportInfo['data']['data'][$datum]['create_time']),
                'status' => $status,
                'tips' => $tips,
                'pop' => $pop ?? [],
                'is_cancel' => $is_cancel,
                'refundPercent' => $refundPercent
            ];
        }
        return $data;
    }

    /**
     * 定制报告详情
     * @return Json
     * @throws Exception
     */
    public function customReportDetail(): Json
    {
        $id = input('id/s', '');
        if (!$id)
        {
            return show(0, '请求参数异常');
        }
        $questionModel = new ZlcrCustomReportQuestion();
        $question = $questionModel->getInfoById($id);
        if (empty($question) || (isset($question['uid']) && (int)$question['uid'] !== $this->user['id']))
        {
            return show(config('code.error'), '数据不存在');
        }
        $question['status'] = (int)$question['status'];
        //处理报告已读状态
        if (!$question['is_read'])
        {
            $questionModel->updateData($question['uid'], $id, ['is_read' => 1]);
            $questionModel->listDataDel($this->user['id'], [$id], 1);
        }

        //获取报告结果信息
        $questionResult = (new ZlcrCustomReportQuestionInfo())->getInfoById($id);
        $tips = '';
        $is_remark = 0;
        $tagList = null;
        switch ($question['status'])
        {
            case 1://问题待审核
            case 2://等待接单
            case 3://问题待解答
            case 4://解答待审核
            case 13://问题待解答（答案审核未通过)
                return show(config('code.error'), '报告还未出炉，请耐心等待～');
            case 5://已完成待评价
                $tagModel = new ZlcrTag();
                $tag = $tagModel->getLevelTag(2, 0);
                $tagList = $tagModel->getQuestionAllsResrt($tag);
            case 6://已评价待审核
            case 7://评价已审核完成
                $status = 3;//已完成
                //获取对应占星师资料
                $astr = (new ZlcrAstr())->getInfoById($question['astr_id']);
                //获取对应的评论信息
                $comment = (new ZlcrCustomReportQuestionComment())->getInfoById($id);
                //获取对应等级的标签信息
                $tags = [];
                //评论内容
                $remark_data = null;
                //问题被评论
                if ($comment)
                {
                    $is_remark = 1;
                    $tag = (new ZlcrTag())->getLevelTag(2, $comment['level']);
                    foreach ($tag as $item)
                    {
                        $tags[] = [
                            'tname' => $item['tag_name'],
                            'is_checked' => in_array($item['id'], explode(',', $comment['tid']), false) ? 1 : 0
                        ];
                    }
                    $remark_data = [
                        'level' => (int)$comment['level'],
                        'remark' => $comment['comment'],
                        'tags' => $tags,
                        'is_violation' => (int)$comment['status'] === 3 ? 1 : 0 // 是否违规
                    ];
                }
                $res_data = [
                    'astr_name' => $astr['nickname'],
                    'astr_avatar' => $astr['avatar'],
                    'content' => $questionResult['answer_content'],
                    'remark_data' => $remark_data
                ];
                break;
            case 10://问题审核未通过失效
            case 11://订单派发超时失效
            case 12://占星师超时未完成失效
            case 14://占星师拒答两次失效
            case 15://取消订单，金额退回90%
            case 16://取消订单，金额全部退回
                $status = 4;//已失效
                $tips = '7个工作日内退款至原支付账户';
                if ($question['status'] === 10)
                {
                    $msg = '您好，该报告订单因提问内容不符合平台规范失效，退款金额将在７个工作日内原路返回，敬请谅解';
                } elseif ($question['status'] === 11)
                {
                    $msg = '您好，该报告因订单派发超时失效，退款金额将在７个工作日内原路返回，敬请谅解';
                } elseif ($question['status'] === 12)
                {
                    $msg = '您好，该报告订单因占星师超时未完成失效，退款金额将在７个工作日内原路返回，赔偿您月运免费卷已经发送至卡劵中心，带来的不便敬请谅解';
                } elseif ($question['status'] === 14)
                {
                    $msg = '您好，该报告订单因过多占星师反馈无法回复失效，退款金额将在７个工作日内原路返回，敬请谅解';
                } elseif ($question['status'] === 15)
                {
                    $tips = '7个工作日内退款至原支付账户';
                    $msg = '您好，该报告订单已为你取消，因占星师已在制作中扣除10%订单金额，望您谅解，退款金额将在７个工作日内原路返回，具体以支付渠道为准';
                } elseif ($question['status'] === 16)
                {
                    $tips = '7个工作日内退款至原支付账户';
                    $msg = '您好，该报告订单已为你取消，退款金额将在７个工作日内原路返回，具体以支付渠道为准';
                } else
                {
                    $msg = '您好，该报告订单因提问内容不符合平台规范失效，款项将在7个工作日内原渠道返回，敬请谅解';
                }
                $fail_info = [
                    'msg' => $msg,
                    'zhunle' => '准了占星团队',
                    'time' => $question['invalid_time'] ? date('Y.m.d H:i', $question['invalid_time']) : date('Y.m.d H:i'),
                ];
                break;
            default:
                return show(config('code.error'), '报告结果暂未出炉，请耐心等候');
        }
        $data = [
            'is_merge' => $question['is_merge'],
            'rid1' => $questionResult['rid1'],
            'rid2' => $questionResult['rid2'],
            'question_name' => $question['question_name'],
            'create_time' => date('Y.m.d H:i', $question['create_time']),
            'status' => $status,
            'tips' => $tips,
            'fail_info' => $fail_info ?? null,
            'is_remark' => $is_remark,
            'res_data' => $res_data ?? null,
            'tag_list' => $tagList
        ];
        return show(200, '请求成功', $data);
    }

    /**
     * 评论定制报告
     * @return Json
     * @throws ApiException
     * @throws Exception
     */
    public function commentCustomReport(): Json
    {
        $cache = Cache::get('report_comment' . $this->user['id']);
        if ($cache)
        {
            return show(config('code.error'), '操作频繁，请稍后');
        }
        Cache::set('report_comment' . $this->user['id'], 1, 3);

        $qid = input('qid/s', '');
        $level = input('level/d', 0);
        $tid = input('tid/d', 0);
        $remark = input('remark/s', '');
        if (!$qid || !$level || !$tid)
        {
            return show(0, '请求参数异常');
        }
        if (mb_strlen($remark) > 200)
        {
            return show(config('code.error'), '您的热情超过了我的承受范围');
        }

        // if (empty($remark))
        // {   // 无评论内容
        //     $status = 7;    // 评价已审核完成
        // } else
        // {
        //     $res = AliyunFilterWord::checkText($remark, 'article_comment');
        //     //若内容有违规且超过配置的相似比例，则进行隐藏不显示，将标签存入库中
        //     if ($res)
        //     {
        //         return show(0, '评价内容涉嫌' . $res['label'] . '，请重新设置');
        //     }
        //     $status = 6; // 6=>已评价待审核
        // }
        $status = 7;    // 评价已审核完成
        if ($remark)
        {
            $res = AliyunFilterWord::checkText($remark, 'article_comment');
            //若内容有违规且超过配置的相似比例，则进行隐藏不显示，将标签存入库中
            if ($res)
            {
                return show(0, '评价内容涉嫌' . $res['label'] . '，请重新设置');
            }
        }

        $questionModel = new ZlcrCustomReportQuestion();
        $question = $questionModel->getInfoById($qid);

        //数据不存在或未完成或已被评论都不可评论
        if (!$question || (int)$question['uid'] !== $this->user['id'] || (int)$question['status'] !== 5)
        {
            return show(config('code.error'), '数据不存在');
        }
        $tag = (new ZlcrTag())->getInfoById($tid);
        //评论等级和标签等级不符，不可评论
        if (!$tag || (int)$tag['flag'] !== $level)
        {
            return show(config('code.error'), '请求异常');
        }
        $insertData = [
            'qid' => $qid,
            'level' => $level,
            'tid' => $tid,
            'status' => $status === 6 ? 1 : 2,  // 免审核 自动审核通过 状态 1=>待审核 2=>审核通过
            'comment' => $remark,
            'astr_id' => (int)$question['astr_id'],
            'comment_type' => 1,
            'create_time' => time()
        ];
        // 写入评论信息
        (new ZlcrCustomReportQuestionComment())->saveData($insertData);
        // 更新定制报告状态
        $questionModel->updateData($question['uid'], $qid, ['status' => $status]);
        // 写入待审核数据
        if ($status === 6)
        {   // 添加待审核数据信息
            (new ZlcrContentCheck())->saveData([
                'type' => 3, // 评论内容审核
                'status' => 1,
                'qid' => $qid,
                'create_time' => $this->request->time()
            ]);
        } elseif ($status === 7)
        {   // 免审核 自动更新占星师能力分
            (new ZlcrAstr())->changeAstrGrade($insertData['astr_id'], $qid, (int)$tag['score']);
        }

        #神策打点 101 定制报告评价 CustomReportComment
        $sensorsTrackData = [
            'question_id' => $qid,// 问题ID
            'question_name' => $question['question_name'],// 问题名称
            'remark_level' => $level,// 评价星级
            'remark_tag' => $tag['tag_name'],// 评价标签
            'remark_content' => $remark,// 评价内容
        ];
        SensorsData::track($this->user['id'], true, 'CustomReportComment', $sensorsTrackData);

        return show(200, '评论成功', current($insertData));
    }

    /**
     * 取消报告
     * @return Json
     * @throws Exception
     */
    public function refundReport()
    {
        #神策打点 102 定制报告取消订单 CustomReportCancel
        $sensorsTrackData = [
            'question_id' => '',// 问题ID
            'question_name' => '',// 问题名称
            'is_received' => false,// 是否被接单
            'order_id' => '',// 订单编号
            'is_merge' => false,// 是否合盘
            'pay_time' => '',// 下单时间
            'is_success' => false,// 是否成功
            'failed_reson' => '',// 失败原因
        ];
        $sensorsEventName = 'CustomReportCancel';

        $order_id = input('order_id/s', '');
        $status = input('status/d', 0);//0=>等待审核 1=>等待接单，2=>进行中，3=>已完成(去查看)，4=>已失效
        if (!$order_id || !$status)
        {
            return show(0, '请求异常');
        }
        $sensorsTrackData['order_id'] = $order_id;

        $questionModel = new ZlcrCustomReportQuestion();
        $questionGoodsModel = new ZlcrCustomReportGoods();
        $OrderModel = new \app\common\cachemodel\Orders();
        //获取订单支付金额等信息
        $orders = $OrderModel->getInfoById($order_id);
        if (!$orders || $orders['uid'] != $this->user['id'] || $orders['order_type'] != 15)
        {
            return show(0, '数据不存在');
        }
        //获取问题信息
        $question = $questionModel->getOrderNumQuestionFromCache($order_id);
        $cache = Cache::get('custom_report_cancel');
        if ($cache)
        {
            return show(0, '该订单已完成不可取消');
        }
        Cache::set('custom_report_cancel', $question['id'], 1);
        if (!$question || $question['uid'] != $this->user['id'])
        {
            return show(0, '数据不存在');
        }
        $questionInfo['ids'] = [$question['id']];
        $questionInfo['data']['data'] = [$question['id'] => $question];
        $data = current($this->resetReport($questionInfo, $questionModel));
        $data['status'] = (int)$data['status'];

        $sensorsTrackData['question_id'] = $question['id'];
        $sensorsTrackData['question_name'] = $question['question_name'];
        $sensorsTrackData['is_merge'] = $question['is_merge'] > 0;
        $sensorsTrackData['pay_time'] = $question['pay_time'];
        //当前数据可以被取消且订单状态无变化则执行退款操作
        if ($data['is_cancel'] && $data['status'] === $status)
        {
            // 问题待接单状态删除问题池，检测该问题是否已被接单
            if ($data['status'] === 1)
            {
                //定制报告问题接单池 删除当前问题
                $delNum = $questionModel->CustomReportQueueDel($question['id']); //  返回从问题池内删除问题数量
                if (!$delNum)
                {   // 删除数量不为真，订单可能被接单了
                    //数据库查询问题状态  0=>待支付 1=>问题待审核 2=>问题待接单 3=>问题待解答 4=>解答待审核 5=>已完成待评价 6=>已评价待审核 7=>评价已审核完成 10=>问题审核未通过失效 11=>订单派发超时失效 12=>占星师超时未完成失效 13=>问题待解答（答案审核未通过）14=>占星师拒答三次或申诉通过失效 15=>用户取消订单，金额退回90% 16=>用户取消订单，金额全部退回
                    $info = Db::table('wechat_backup_07_18_14_43_00.zlcr_custom_report_question')->where(['order_num' => $order_id])->field('status')->find();
                    $info['status'] = $this->getReportStatus($info);
                    if ($info['status'] == 2)
                    {
                        $data['pop'] = [
                            'tips' => '该订单已被占星师接单，现在取消只返还订单金额的90%，是否取消订单？',
                            'title' => '取消订单',
                            'type' => 2
                        ];
                        $sensorsTrackData['is_received'] = true;
                        $sensorsTrackData['is_success'] = false;
                        $sensorsTrackData['failed_reson'] = '该订单已被占星师接单，现在取消只返还订单金额的90%，是否取消订单？';
                        SensorsData::track($this->user['id'], true, $sensorsEventName, $sensorsTrackData);
                        return show(200, '请求成功', $data);
                    }
                }
            }
            //开始执行退款操作
            $data['pop'] = [
                'tips' => '订单金额将在1-7个工作日内退款至原支付账户，具体以支付渠道为准',
                'title' => '订单取消成功',
                'type' => 1
            ];
            $data['status'] = 4;
            $data['tips'] = '7个工作日内退款至原支付账户';
            $refundPrice = $orders['total_amount'] * $data['refundPercent'];
            //处理退款逻辑
            $res = $OrderModel->refund($this->user['id'], $orders, $refundPrice);
            if ($res['status'])
            {
                //当前问题报告状态
                if ($data['refundPercent'] === 1)
                {
                    $customStatus = 16;//百分百退款
                } else
                {
                    $customStatus = 15;//退款百分之九十
                }
                //更新问题为失效状态
                (new ZlcrCustomReportQuestion())->updateData($this->user['id'], $question['id'], ['status' => $customStatus, 'invalid_time' => time()]);

                //库存还原
                $questionGoodsModel->resetGoodsIndexNum();

                //若当前问题是已接单的状态则需要通知占星师
                if ($customStatus === 15)
                {
                    $astrPrice = $orders['total_amount'] - $refundPrice;
                    // 扣除手续费和营业税
                    $astrPrice = Util::getAfterTaxAmount($astrPrice);

                    $astrAccountModel = new ZlcrAstrAccount();
                    //获取占星师账户信息
                    $astrAccountInfo = $astrAccountModel->getAstrAccountInfo($question['astr_id']);

                    $accountData = [
                        'balance' => $astrAccountInfo['balance'] + $astrPrice,
                        'total_amount' => $astrAccountInfo['total_amount'] + $astrPrice,
                        'update_time' => request()->time()
                    ];
                    // 占星师账户更新
                    $astrAccountModel->updateData($astrAccountInfo['id'], $question['astr_id'], $accountData);

                    $accountRecord = [
                        'astr_id' => $question['astr_id'],
                        'type' => 1,
                        'gid' => $question['gid'],
                        'qid' => $question['id'],
                        'good_amount' => $orders['total_amount'],
                        'proportion' => 0.1,
                        'amount' => $astrPrice,
                        'balance' => $accountData['balance'],
                        'create_time' => $accountData['update_time'],
                        'question_type' => 1
                    ];
                    //添加占星师流水记录
                    (new ZlcrAstrAccountRecord())->addRecord($question['astr_id'], $accountRecord);
                    //发送短信和站内信
                    $astrInfo = (new ZlcrAstr())->getInfoById($question['astr_id']);
                    Util::sendYxSms([$astrInfo['tel']], $extend = '', 30159, ['question_num' => $question['id']]);
                    (new ZlcrAstrMessage())->add($question['astr_id'], [
                        'status' => 0,
                        'is_read' => 0,
                        'astr_id' => $question['astr_id'],
                        'type' => 9, // 占星师违规消息
                        'title' => '用户取消定制报告订单',
                        'content' => "您的编号为{$question['id']}的定制报告，因用户原因已经取消，该订单金额的10%赔付给您，详情见我的收益",
                        'target' => '',
                        'link' => '',
                        'create_time' => time()
                    ]);
                    // 如果占星师已经接单了，清空已经接单的占星师，“进行中的任务”的缓存
                    (new ZlcrAstr())->underwayTaskDel((int)($question['astr_id']), [$question['id']]);

                    $sensorsTrackData['is_received'] = true;
                }
                //发送钉钉消息
                Util::sendZlcrMsg(6, ['用户uid:' . $question['uid'], '问题:' . $question['question_name'], '状态:' . ($customStatus === 15 ? '占星师已接单，退款90%' : '占星师未接单，全部退款'),]);

                $sensorsTrackData['is_success'] = true;
                $sensorsTrackData['failed_reson'] = '';
                SensorsData::track($this->user['id'], true, $sensorsEventName, $sensorsTrackData);
            } else
            {
                $data['pop'] = [
                    'tips' => $res['msg'],
                    'title' => '订单取消失败',
                    'type' => 1
                ];
                $sensorsTrackData['is_success'] = false;
                $sensorsTrackData['failed_reson'] = $res['msg'];


                return show(200, '请求成功', $data);
            }
        }
        return show(200, '请求成功', $data);
    }

    /**
     * 获取报告状态
     * @param $question
     * @return int
     */
    private function getReportStatus($question)
    {
        switch ($question['status'])
        {
            case 1://问题待审核
                $status = 0;
                break;//等待接单
            case 2://等待接单
                $status = 1;//等待接单
                break;
            case 3://问题待解答
            case 4://解答待审核
            case 13://问题待解答（答案审核未通过)
                $status = 2;//进行中
                break;
            case 5://已完成待评价
            case 6://已评价待审核
            case 7://评价已审核完成
                $status = 3;//已完成

                break;
            case 10://问题审核未通过失效
            case 11://订单派发超时失效
            case 12://占星师超时未完成失效
            case 14://占星师拒答两次失效
            case 15://取消订单，金额退回90%
            case 16://取消订单，金额全部退回
                $status = 4;//已失效
                break;
            default:
                $status = 0;
                break;
        }
        return $status;
    }
}
